/***
 * Der Workflowcontroler regelt alle Abläufe im Programmbereich "Workflow"
 * Er nimmt Events entgegen (Tabwechsel und Buttonklicks) entgegen und veranlasst 
 * entsprechende Abläufe
 ***/
package de.previsor.workflow.control;
import de.previsor.workflow.MainApp;
import de.previsor.workflow.model.Mitarbeiter;
import de.previsor.workflow.model.TempData;
import de.previsor.workflow.control.helper.Task;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.regex.Pattern;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

/**
 *
 * @author Haikel, Robert, Thomas, Michael
 */
public class WorkFlowController implements Initializable {
    
    @FXML private TextField inp_pname;    
    @FXML private TextField inp_fname; 
    @FXML private TextField inp_street;
    @FXML private TextField inp_nbr;
    @FXML private TextField inp_city;
    @FXML private TextField inp_plz;
    @FXML private TextField inp_path;
    @FXML public DatePicker dtpck_date;
    @FXML public TextArea txta_desc;
    @FXML public TextArea txta_note;
    @FXML public Label lbl_path;
    @FXML public Label lbl_duedate;
    @FXML public ComboBox cmb_state;
    
    
    @FXML private Button SaveTaskButton;
    @FXML private TabPane UITabPane;
    @FXML private Tab TaskOverview;
    @FXML private TextField FilterIDTextField;
    @FXML private TextField FilterTitleTextField;
    @FXML private CheckBox AllCheckBox;
    @FXML private CheckBox OpenCheckBox;
    @FXML private CheckBox ClosedCheckBox;    
    @FXML private TableView<Task> TaskTable;
    @FXML private TableColumn<Task, String> IDCol;
    @FXML private TableColumn<Task, String> TitleCol;
    @FXML private TableColumn<Task, String> CompanyCol;
    @FXML private TableColumn<Task, String> AdressCol;
    @FXML private TableColumn<Task, String> DueCol;
    @FXML private TableColumn<Task, String> StatusCol;    
    ObservableList<Task> data = FXCollections.observableArrayList();  
   
    @FXML public TextArea txta_errors;    
    @FXML AnchorPane userOverview;      //Profilübersicht der Mitarbeiter
    @FXML AnchorPane aufgabenOverview;  //Aufgaben
    
    DBConnect dbcon;
    
    private static String OS = null;
    
    public int initialized;
    private static final int abstand = 20;
    private static final int feldBreite = 370;
    private static final int feldHoehe = 200;
    
    private int x1 = 20;
    private int x2 = abstand*2 + feldBreite;
    private int y = 60;
    private int ysteigt =  feldHoehe + abstand;
    int i = 1;
    
    @FXML private GridPane tasktable;
    
    
    private ArrayList<Mitarbeiter> kollegen;
    
    @FXML  
    private void profileAnzeigen(Event event) {
 
        
       //userOverview.getChildren().clear();
       y=60;
       kollegen = TempData.getAllMitarbeiter();       
    
        System.out.println("Anzahl Mitarbeiter :: " + kollegen.size());
        Iterator<Mitarbeiter> iter = kollegen.iterator();
        
        
       
       while(iter.hasNext()){          
        Mitarbeiter m = iter.next();
        try{          
          
         
           AnchorPane profil = (AnchorPane) FXMLLoader.load(MainApp.class.getResource("view/profil.fxml")); 
           initialized = 1;
           
           
           TextField nachname = (TextField) profil.lookup("#inp_name");
           nachname.setText(m.getNachname());
           
           TextField email = (TextField) profil.lookup("#inp_email");
           email.setText(m.getEmail());
           
           TextField bereich = (TextField) profil.lookup("#inp_bereich");
           bereich.setText(m.getBereich());
           
           TextField recht = (TextField) profil.lookup("#inp_recht");
           recht.setText(m.getRechte());
          
           
           if(i == 1)
           {
                
                profil.setLayoutY(60);
                profil.setLayoutX(abstand);
                
           }
           
            else if (i % 2 == 0){
                  
                    
                    profil.setLayoutY(y);
                    profil.setLayoutX(x2);
                    
                    
                    
                    
                   System.out.println(i + "Plane____");
                   System.out.println(x2 + "  X-Wert____");
                   System.out.println(y + "  Y-Wert____");
                   
                    y= y + ysteigt;
                    
                }
            else if (i % 2 == 1){
                    
                   System.out.println(i + "Plane____");
                   System.out.println(x1 + "  X-Wert____");
                   System.out.println(y + "  Y-Wert____");
                    
                    profil.setLayoutY(y);                    
                    profil.setLayoutX(x1);
       
    
                }
         
           
           userOverview.getChildren().add(profil);
        }catch(Exception e){
            e.printStackTrace();
            //System.out.println("Etwas wurde geworfen");
        }        
        i ++;
    } // ENDE While-Schleife
       
    } 
    
    @FXML  
    private void profilHinzufuegen(ActionEvent event) {
        
        try{    
            
            System.out.println(i);
             AnchorPane profilnew = (AnchorPane) FXMLLoader.load(MainApp.class.getResource("view/profil.fxml")); 
        
        if(i == 1)
           {
                
                profilnew.setLayoutY(60);
                profilnew.setLayoutX(abstand);
                
           }
           
            else if (i % 2 == 0){
                  
                    
                    profilnew.setLayoutY(y);
                    profilnew.setLayoutX(x2);
                    
                    
                    
                    
                   System.out.println(i + "Plane____");
                   System.out.println(x2 + "  X-Wert____");
                   System.out.println(y + "  Y-Wert____");
                   
                    y= y + ysteigt;
                    
                }
            else if (i % 2 == 1){
                    
                   System.out.println(i + "Plane____");
                   System.out.println(x1 + "  X-Wert____");
                   System.out.println(y + "  Y-Wert____");
                    
                    profilnew.setLayoutY(y);                    
                    profilnew.setLayoutX(x1);
       
    
                }
        
        
        userOverview.getChildren().add(profilnew);
        }catch(Exception e){
            e.printStackTrace();
      
        }   
        i++;
    }
    

    @FXML
    public void showTasks(ActionEvent event)
    {
        dbcon = new DBConnect();
        data.clear();
        String status = null ;       
        
        
        for(String[] s : dbcon.getTasks())        
        {
            if(s[9].equals("0")) status = "offen";
            if(s[9].equals("1")) status = "abgeschlossen";
            
            if(OpenCheckBox.isSelected() && s[9].equals("0"))            
            {
                Task t = new Task(s[0],s[1],s[2], (s[3]+" "+s[4]+" "+s[5]+" "+s[6]),s[7],status);

                if(s[0].contains(FilterIDTextField.getText()) && s[1].contains(FilterTitleTextField.getText()))
                {
                    data.add(t);
                }              
            }
            if(ClosedCheckBox.isSelected() && s[9].equals("1"))
            {
                Task t = new Task(s[0],s[1],s[2], (s[3]+" "+s[4]+" "+s[5]+" "+s[6]),s[7],status);
                if(s[0].contains(FilterIDTextField.getText()) && s[1].contains(FilterTitleTextField.getText()))
                {
                    data.add(t);
                }     
            }
            if(!OpenCheckBox.isSelected() && !ClosedCheckBox.isSelected())
            {
                Task t = new Task(s[0],s[1],s[2], (s[3]+" "+s[4]+" "+s[5]+" "+s[6]),s[7],status);
                if(s[0].contains(FilterIDTextField.getText()) && s[1].contains(FilterTitleTextField.getText()))
                {
                    data.add(t);
                }     
            }
             
        }   
    }
    
    @FXML
    private void editTask(ActionEvent event, String title)
    {
        UITabPane.getSelectionModel().select(TaskOverview);
        
        SaveTaskButton.setText("Speichern");
        
        for(String[] s : dbcon.getTasks())
        {
            if(s[1].equals(title))                
            {
                inp_pname.setText(s[1]);
                inp_fname.setText(s[2]);
                inp_street.setText(s[3]);
                inp_city.setText(s[6]);                
                inp_nbr.setText(s[4]);
                inp_plz.setText(s[5]);
                txta_desc.setText(s[10]);
                txta_note.setText(s[11]);         

            }
        
        }
        
    
    
    
    
    
    }
    
    @FXML 
    public void FilterHandler(ActionEvent event)
    {
        if(event.getSource().equals(AllCheckBox)) 
        {
            if(AllCheckBox.isSelected())
            {
                OpenCheckBox.setDisable(true);
                ClosedCheckBox.setDisable(true);
            }
            else
            {
                OpenCheckBox.setDisable(false);
                ClosedCheckBox.setDisable(false);
            }
        }
        
        if(event.getSource().equals(OpenCheckBox)) 
        {
            if(OpenCheckBox.isSelected())
            {
                AllCheckBox.setDisable(true);
                ClosedCheckBox.setDisable(true);
            }
            else
            {
                AllCheckBox.setDisable(false);
                ClosedCheckBox.setDisable(false);
            }
        }
        
        if(event.getSource().equals(ClosedCheckBox)) 
        {
            if(ClosedCheckBox.isSelected())
            {
                AllCheckBox.setDisable(true);
                OpenCheckBox.setDisable(true);
            }
            else
            {
                AllCheckBox.setDisable(false);
                OpenCheckBox.setDisable(false);
            }
        }      
    }
    
    
    /*
    @FXML
    public void showTasks(ActionEvent event)
    {
        dbcon = new DBConnect();
        data.clear();
        String status = null ;        
        
        for(String[] s : dbcon.getTasks())        
        {
            if(s[9].equals("0")) status = "offen";
            if(s[9].equals("1")) status = "abgeschlossen";

            Task t = new Task(s[0],s[1],s[2], (s[3]+" "+s[4]+" "+s[5]+" "+s[6]),s[7],status);
            data.add(t);
            
        }   
    }
    */
    
    
    
   
    public int parseState(String state){
        if(state == "Neu") return 1;
        if(state == "Angenommen") return 2;
        if(state == "Wände") return 3;
        if(state == "Objekte") return 4;
        if(state == "Texturieren") return 5;
        if(state == "Möbilieren") return 6;
        if(state == "Beendet") return 7;
        if(state == "Überholt") return 8;
        else return 0;
    }
    public String returnState(int state)
    {
        if(state == 1) return "Neu";
        if(state == 2) return "Angenommen";
        if(state == 3) return "Wände";
        if(state == 4) return "Objekte";
        if(state == 5) return "Texturieren";
        if(state == 6) return "Möbilieren";
        if(state == 7) return "Beendet";
        if(state == 8) return "Überholt";
        else return "Kein State";
    }
     @FXML
    public void createJob(ActionEvent event){
        boolean state = false;
        DBConnect db = new DBConnect();
        
        System.out.println("Auftrag wird erstellt...");
        
        String Auftragsname = inp_pname.getText();
        String Firmenname = inp_fname.getText();
        String Straße = inp_street.getText();
        String Hausnummer = inp_nbr.getText();
        String Stadt = inp_city.getText();
        String Postleitzahl = inp_plz.getText();
        String Beschreibung = txta_desc.getText();
        String Notiz = txta_note.getText();
        String Bildpfad = inp_path.getText();
        Integer PLZ=1;
        Integer Hnbr=1;
        Integer Status=1;
        Date date = null;
        
        LocalDate todayLocal = null;
        Status = parseState(cmb_state.getValue().toString());
       
        ArrayList<String> Errors = new ArrayList<String>();
        //Testen der eingegebenen Werte
        
        //Empty Fields Test
        if("".equals(Beschreibung))
        {
            state = false;
            Errors.add("Keine Beschreibung angegeben!");
        }
        else state = true;
        if("".equals(Notiz))
        {
            state = false;
            Errors.add("Keine Notiz angegeben!");
        }
        else state = true;
        if("".equals(Auftragsname))
        {
            state = false;
            Errors.add("Kein Auftragsname angegeben!");
        }
        else
        {
            state = true;
        }
        
        if("".equals(Firmenname))
        {
            state = false;
            Errors.add("Kein Firmenname angegeben!");
        }
        else
        {
            state = true;
        }
        
        if("".equals(Straße))
        {
            state = false;
            Errors.add("Kein Straßenname angegeben!");
        }
        else
        {
            state = true;
        }
        if("".equals(Stadt))
        {
            state = false;
            Errors.add("Kein Stadtname angegeben!");
        }
        else
        {
            state = true;
        }
        if("".equals(Postleitzahl))
        {
            state = false;
            Errors.add("Keine Postleitzahl angegeben!");
        }
        else
        {
            state = true;
        }
        if("".equals(Hausnummer))
        {
            state = false;
            Errors.add("Keine Hausnummer angegeben!");
        }
        else
        {
            state = true;
        }
        //Ende Empty Fields Test
        

        if (Pattern.matches("[a-zA-Z]+", Postleitzahl) == false && Postleitzahl.length() == 5){
             state = true;
            
             System.out.println("PLZCode :: valid");
             PLZ = Integer.valueOf(Postleitzahl);
             if(String.valueOf(PLZ).length()<5)
             {
                 //System.out.println("0"+PLZ.toString());
             }
             else
             {
                 //System.out.println(PLZ.toString());
             }
             
        }
        else 
        {
            Errors.add("Postleitzahl fehlerhaft!");
            state = false;
            //System.out.println("PLZCode :: invalid");
        }
        
        if (Pattern.matches("[a-zA-Z]+", Hausnummer) == false && Hausnummer.length() > 0){
             state = true;
             //System.out.println("HNbr :: valid");
             Hnbr = Integer.valueOf(Hausnummer);
             
        }
        else 
        {
            Errors.add("Hausnummer fehlerhaft!");
            state = false;
            //System.out.println("PLZCode :: invalid");
        }
        
        
        
        
        Mitarbeiter thisUser = TempData.getBenutzer();
        String ActUser = thisUser.getVorname() + " " + thisUser.getNachname();
        
        
        LocalDate datePick = dtpck_date.getValue();
        if(datePick == null)
        {
            
        }
        else
        {
            Date todayDate = new Date();
            todayLocal = todayDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        }
        if(datePick == null)
        {
            state = false;
            Errors.add("Datum fehlerhaft!");
        }
        else if(datePick.compareTo(todayLocal) < 1)
        {
            
            state = false;
            Errors.add("Datum liegt in der Vergangenheit !");
        }
        else
        {
            state = true;
            date = Date.from(datePick.atStartOfDay(ZoneId.systemDefault()).toInstant());
        }
        
        if(state)
        {
            txta_errors.setOpacity((double) 0);
            if(Errors.isEmpty())
            {
            
            db.addTask(Auftragsname,Firmenname,Straße,Hnbr,PLZ,Stadt,date.toString(),ActUser,Status,Beschreibung,Notiz,Bildpfad);
            try
            {
            if(isWindows() == false)
            {
            lbl_duedate.setText("Auftrag erstellt,Sie nutzen" + OS);
            }
            else
            {
                lbl_duedate.setText("Auftrag erstellt, leider nutzen Sie" + OS);
            }
            }
            catch(Exception e){
            System.out.println("Alert nicht unterstützt!");
        }        
            }
            }
        else
        {
            System.out.println(Errors);
            txta_errors.setEditable(false);
            int i = 0;
            int length = Errors.size();
            while(i < length)
            {
               txta_errors.setText(txta_errors.getText() + "\n" + Errors.get(i));
               i++;
            }
            txta_errors.setOpacity((double) 1);
            txta_errors.setVisible(true);

        }
           
    }
   @FXML
   private void fill_states(ActionEvent event)
   {
       //System.out.println("Status geladen");
   }    
   
    @FXML
    private void choose(ActionEvent event)
    {
        FileChooser fileChooser = new javafx.stage.FileChooser();
        File file = fileChooser.showOpenDialog(new Stage());
        inp_path.setOpacity((double) 1);
        lbl_path.setOpacity((double) 1);
        if (file != null) inp_path.setText(file.getAbsolutePath());  
    }
    
   public static String getOsName()
   {
      if(OS == null) { OS = System.getProperty("os.name"); }
      return OS;
   }
    
    public static boolean isWindows()
   {
      return getOsName().startsWith("Windows");
   }

    
    @Override
    public void initialize(URL url, ResourceBundle rb) {  
        
        
        TaskTable.setOnMouseClicked(event -> {
            if (event.getClickCount() == 2 && !TaskTable.getSelectionModel().getSelectedItem().getTitle().equals("") ) {  
                editTask(new ActionEvent(event.getSource(), TaskTable), TaskTable.getSelectionModel().getSelectedItem().getTitle());
            }
        });

        try
        {
        IDCol.setCellValueFactory(new PropertyValueFactory<Task,String>("ID"));
        TitleCol.setCellValueFactory(new PropertyValueFactory<Task, String>("Title"));
        CompanyCol.setCellValueFactory(new PropertyValueFactory<Task, String>("Company"));
        AdressCol.setCellValueFactory(new PropertyValueFactory<Task, String>("Adress"));
        DueCol.setCellValueFactory(new PropertyValueFactory<Task, String>("Due"));
        StatusCol.setCellValueFactory(new PropertyValueFactory<Task, String>("status"));     
        TaskTable.setItems(data);    
        
        

        }
        catch(Exception e){
            System.out.println("Fehler bei Tabellenerstellung");
        }
        try 
        {
            cmb_state.getItems().addAll("Neu",
            "Angenommen", 
            "Wände", 
            "Objekte", 
            "Texturieren", 
            "Möbilieren", 
            "Beendet", 
            "Überholt");
        }
        catch(Exception e){
            System.out.println("Fehler bei Combobox");
            //System.out.println("Etwas wurde geworfen");
        }
        
    }
    
 /***
    * Autor: Michael Müller
    * 
    * Zeigt Aufträge im Tab "Aufträge"
    * Ist für die Zukunft so gedacht, dass die Aufgaben je nach User entsprechend ausgegeben werden sollen.
    * So erhält der Modellierer nur die Aufträge mit dem Status Modellierung und der Wohnungsmodellierer
    * nur die Aufgaben der ersten Instanz (Wände und Decken Modellieren ...)
    * Die Selektion der Aufträge ist jedoch noch nicht implementiert
    * 
    * @param event --> wird ausgelöst wenn man den Tab "Aufträge" anklickt
    ***/
   @FXML  
   private void auftraegeAnzeigen(Event event) {
       
        // Leeren der Übersicht bei jedem Neuaufruf 
        aufgabenOverview.getChildren().clear();
        // Aufbau der DB Verbindung um alle Aufträge zu holen
        DBConnect con = new DBConnect();
        ArrayList<String[]> auftraege = con.getTasks();
        
        Iterator<String[]> iter = auftraege.iterator(); 
        
        // Platzierung der Auftragpanels in der Übersicht
        int x = 15;
        int y = 0;
       
       //Je Auftrag wird ein leeres Panel geladen und mit Daten gefüllt
       while(iter.hasNext()){ 
           // Enthält Auftragsdaten aus der DB
           String[] auftrag = iter.next();
           String titelText = auftrag[1];
           String firmaText = auftrag[2];
           String fristText = auftrag[7];
           String statusText = auftrag[9];
                 
            try { 
                // Laden des leeren Panels
                AnchorPane panel = (AnchorPane) FXMLLoader.load(MainApp.class.getResource("view/AuftragPanel.fxml"));
                // Manipulation der Komponenten des Panels
                Label titel = (Label)panel.lookup("#lbl_titel");
                titel.setText(titelText);
                Label firma = (Label)panel.lookup("#lbl_firma");
                firma.setText(firmaText);
                Label frist = (Label)panel.lookup("#lbl_frist");
                frist.setText(fristText);
                Label status = (Label)panel.lookup("#lbl_status");
                status.setText(statusText);

                panel.setLayoutY(x);
                panel.setLayoutY(y);
                
                // Panelhöhe (Layout) anpassen
                y = y + 50;
                // Fügt der Übersicht die einzelnen Panels hinzu
                aufgabenOverview.getChildren().add(panel);

            } catch (IOException ex) {
                ex.printStackTrace();
                System.out.println("Auftragspanel konnte nicht geladen werden");
            } 
       } // End-While
   }
}
